package com.jiantong.lawEnforcing.impl.service;

import com.google.common.base.Throwables;
import com.google.common.collect.Maps;
import com.jiantong.common.util.UserUtil;
import com.jiantong.lawEnforcing.dto.CasesBasicDto;
import com.jiantong.lawEnforcing.enums.LawCasesType;
import com.jiantong.lawEnforcing.impl.dao.CasesBasicDao;
import com.jiantong.lawEnforcing.impl.dao.CasesCheckDao;
import com.jiantong.lawEnforcing.impl.dao.PartiesInformationDao;
import com.jiantong.lawEnforcing.impl.dao.SimplenessCasesDao;
import com.jiantong.lawEnforcing.impl.manager.CasesBasicManager;
import com.jiantong.lawEnforcing.model.CasesBasic;
import com.jiantong.lawEnforcing.model.CasesCheck;
import com.jiantong.lawEnforcing.model.PartiesInformation;
import com.jiantong.lawEnforcing.model.SimplenessCases;
import com.jiantong.lawEnforcing.service.CasesBasicService;
import com.jiantong.lawEnforcing.util.LawUtil;
import io.terminus.boot.rpc.common.annotation.RpcProvider;
import io.terminus.common.model.PageInfo;
import io.terminus.common.model.Paging;
import io.terminus.common.model.Response;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 案件基本信息
 * Created by mz03 on 2017/8/14.
 */
@Slf4j
@Service
@RpcProvider
public class CasesBasicServiceImpl implements CasesBasicService {

    private final CasesBasicDao casesBasicDao;
    private final CasesBasicManager casesBasicManager;
    private final PartiesInformationDao partiesInformationDao;
    private final SimplenessCasesDao simplenessCasesDao;
    private final CasesCheckDao casesCheckDao;

    @Autowired
    public CasesBasicServiceImpl(CasesBasicDao casesBasicDao, CasesBasicManager casesBasicManager, PartiesInformationDao partiesInformationDao, SimplenessCasesDao simplenessCasesDao, CasesCheckDao casesCheckDao) {
        this.casesBasicDao = casesBasicDao;
        this.casesBasicManager = casesBasicManager;
        this.partiesInformationDao = partiesInformationDao;
        this.simplenessCasesDao = simplenessCasesDao;
        this.casesCheckDao = casesCheckDao;
    }

    /**
     * id 查找
     *
     * @param id
     * @return casesBasic
     */
    @Override
    public Response<CasesBasic> finById(Long id) {
        try {
            CasesBasic casesBasic = casesBasicDao.findById(id);
            if (casesBasic != null) {
                return Response.ok(casesBasic);
            } else {
                log.error("casesBasic (id={}) is not found", id);
                return Response.fail("casesBasic.not.found");
            }
        }catch (Exception e){
            log.error("failed to find casesBasic(id={}),cause:{}",id, Throwables.getStackTraceAsString(e));
            return Response.fail("casesBasic.find.fail");
        }
    }

    /**
     * id 查找
     *
     * @param id
     * @return casesBasic
     */
    @Override
    public Response<CasesBasicDto> finCasesBasicDtoById(Long id) {
        try {
            CasesBasic casesBasic = casesBasicDao.findById(id);
            if (casesBasic==null){
                log.error("casesBasic (id={}) is not found", casesBasic.getParties_id());
                return Response.fail("casesBasic.not.found");
            }
            CasesBasicDto casesBasicDto = new CasesBasicDto();
            casesBasicDto.setCasesBasic(casesBasic);
            PartiesInformation partiesInformation = partiesInformationDao.findById(casesBasic.getParties_id());
            if (partiesInformation==null){
                log.error("partiesInformation (id={}) is not found", casesBasic.getParties_id());
                return Response.fail("partiesInformation.not.found");
            }
            casesBasicDto.setPartiesInformation(partiesInformation);
            if (casesBasic.getCases_type().equals(LawCasesType.EMPTY.value())){
                return Response.ok(casesBasicDto);
            }else if (casesBasic.getCases_type().equals(LawCasesType.SIMPLENESS_CASES.value())){//登记为当场处罚
                //根据案件信息id查询出当场处罚单据
                Map<String,Object> map = Maps.newHashMap();
                if (casesBasic.getId() != null){
                    map.put("cases_basic_id",casesBasic.getId());
                }
                List<SimplenessCases> list =  simplenessCasesDao.list(map);
                if (list.size()==0){
                    log.error("simplenessCases (cases_basic_id={}) is not found",casesBasic.getId());
                    return Response.fail("simplenessCases.not.found");
                }
                SimplenessCases simplenessCases = list.get(0);
                casesBasicDto.setSimplenessCases(simplenessCases);
            }else if (casesBasic.getCases_type().equals(LawCasesType.CASES_CHECK.value())){
                Map<String,Object> map = Maps.newHashMap();
                if (casesBasic.getId() != null){
                    map.put("cases_basic_id",casesBasic.getId());
                }

                List<CasesCheck> list =  casesCheckDao.list(map);
                if (list.size()==0){
                    log.error("CasesCheck (cases_basic_id={}) is not found",casesBasic.getId());
                    return Response.fail("CasesCheck.not.found");
                }

                CasesCheck casesCheck = list.get(0);
                casesBasicDto.setCasesCheck(casesCheck);
                return Response.ok(casesBasicDto);
            }
            return Response.fail("案件类型未定");
        }catch (Exception e){
            log.error("failed to find casesBasic(id={}),cause:{}",id, Throwables.getStackTraceAsString(e));
            return Response.fail("casesBasic.find.fail");
        }
    }


    /**
     * 创建新闻新单据
     *
     * @param casesBasic 单据对象
     * @return 主键 id
     */
    @Override
    public Response<Long> create(CasesBasic casesBasic) {
        try {
            //生成案件编号
            String cases_number = "LAW-"+ new Date().getTime();
            casesBasic.setCases_number(cases_number);

            //设置案件办理人id: receiver_id
            casesBasic.setReceiver_id(UserUtil.getUserId());

            casesBasicDao.create(casesBasic);
            return Response.ok(casesBasic.getId());
        }catch (Exception e) {
            log.error("failed.to.create.casesBasic:{}", Throwables.getStackTraceAsString(e));
            return Response.fail("create.casesBasic.failed");
        }
    }

    /**
     * 创建新闻新单据
     *
     * @param casesBasicDto 单据对象
     * @return 主键 id
     */
    @Override
    public Response<Long> createCasesBasicDto(CasesBasicDto casesBasicDto) {
        try{
            return Response.ok(casesBasicManager.createCasesBasic(casesBasicDto));
        }catch (Exception e){
            log.error("failed to create casesBasicDto error :{}", Throwables.getStackTraceAsString(e));
            return Response.fail("casesBasicDto.create.failed");
        }

    }

    /**
     * 更新新闻的单据
     *
     * @param casesBasic 单据对象
     * @return true or false
     */
    @Override
    public Response<Boolean> update(CasesBasic casesBasic) {

        try{
            return Response.ok(casesBasicManager.updateCasesBasic(casesBasic));
        }catch (Exception e){
            log.error("failed to create casesBasicDto error :{}", Throwables.getStackTraceAsString(e));
            return Response.fail("casesBasicDto.create.failed");
        }
 /*       try{
            return Response.ok(casesBasicDao.update(casesBasic));
        }catch (Exception e){
            log.error("failed.to.update.casesBasic:{}",Throwables.getStackTraceAsString(e));
            return Response.fail("update.casesBasic.failed");
        }*/
    }

    /**
     * 根据status分页查询
     *
     * @param pageNo
     * @param pageSize
     * @param status
     * @return
     */
    @Override
    public Response<Paging<CasesBasic>> pagingByStatus(Integer pageNo, Integer pageSize, Integer status, String cause_action, Integer parties_type, String parties_name) {
        try{
            PageInfo pageInfo = new PageInfo(pageNo,pageSize);
            Map<String, Object> criteria = Maps.newHashMap();
            if(status != null){
                criteria.put("status",status);
            }
            if(cause_action != null){
                criteria.put("cause_action",cause_action);
            }
            if(parties_type != null){
                criteria.put("parties_type",parties_type);
            }
            if(parties_name != null){
                criteria.put("parties_name",parties_name);
            }
            return Response.ok(casesBasicDao.paging(pageInfo.getOffset(),pageInfo.getLimit(),criteria));
        }catch (Exception e){
            log.error("failed to find CasesBasic(status={}), cause:{}", status, Throwables.getStackTraceAsString(e));
            return Response.fail("CasesBasic.find.fail");
        }
    }

    /**
     * 根据status分页查询Dto
     * @param pageNo
     * @param pageSize
     * @param status
     * @param cause_action
     * @param parties_type
     * @param parties_name
     * @return
     */
    @Override
    public Response<Paging<CasesBasicDto>> pagingCasesBasicDto(
            Integer pageNo,
            Integer pageSize,
            Integer status,
            String cause_action,
            Integer parties_type,
            String parties_name
            ) {
        Response<Paging<CasesBasic>> response = pagingByStatus(pageNo,pageSize,status,cause_action,parties_type,parties_name);
        try{
            List<CasesBasicDto> casesBasicDtoList = new ArrayList<>();
            List<CasesBasic> list = response.getResult().getData();
            for (CasesBasic casesBasic:list) {
                PartiesInformation partiesInformation = partiesInformationDao.findById(casesBasic.getParties_id());
                if (LawUtil.isPass(partiesInformation,parties_type,parties_name)) {
                    CasesBasicDto casesBasicDto = new CasesBasicDto();
                    casesBasicDto.setCasesBasic(casesBasic);
                    casesBasicDto.setPartiesInformation(partiesInformation);
                    casesBasicDtoList.add(casesBasicDto);
                }
            }
            Paging<CasesBasicDto> casesBasicDtoPaging = new Paging<>(response.getResult().getTotal(),casesBasicDtoList);
            return Response.ok(casesBasicDtoPaging);
        }catch (Exception e){
            log.error("failed to find CasesBasicDto(status={}), cause:{}", status, Throwables.getStackTraceAsString(e));
            return Response.fail("CasesBasicDto.find.fail");
        }
    }

    /**
     * 根据status分页查询Dto
     *
     * @param pageNo
     * @param pageSize
     * @param status
     * @param cause_action
     * @param parties_type
     * @param parties_name         @return
     */
    @Override
    public Response<Paging<CasesBasicDto>> pagingByList(Integer pageNo, Integer pageSize, Integer status, String cause_action, Integer parties_type, String parties_name) {
        try{
            PageInfo pageInfo = new PageInfo(pageNo,pageSize);
            Map<String, Object> criteria = Maps.newHashMap();
            if(status != null){
                criteria.put("status",status);
            }
            if(cause_action != null){
                criteria.put("cause_action",cause_action);
            }
            if(parties_type != null){
                criteria.put("parties_type",parties_type);
            }
            if(parties_name != null){
                criteria.put("parties_name",parties_name);
            }
            Paging<CasesBasic> paging =casesBasicDao.paging(pageInfo.getOffset(),pageInfo.getLimit(),criteria);
            List<CasesBasic> list = paging.getData();
            List<CasesBasicDto> casesBasicDtoList = new ArrayList<>();

            for (CasesBasic casesBasic:list) {
                PartiesInformation partiesInformation = partiesInformationDao.findById(casesBasic.getParties_id());
                CasesBasicDto casesBasicDto = new CasesBasicDto();
                casesBasicDto.setCasesBasic(casesBasic);
                casesBasicDto.setPartiesInformation(partiesInformation);
                casesBasicDtoList.add(casesBasicDto);
            }
            return Response.ok(new Paging<>(paging.getTotal(),casesBasicDtoList));
        }catch (Exception e){
            log.error("failed to find CasesBasic(status={}), cause:{}", status, Throwables.getStackTraceAsString(e));
            return Response.fail("CasesBasic.find.fail");
        }
    }
}
